const { ObjectId } = require('mongodb');
const crypto = require('crypto');
const token = require('./token');
const sms = require('./sms');
const {key} = require('../config/base');

/**
 * 
 * @param {data,msg,code} param 
 * @returns Object
 */
function formatData({ data = [], msg = 'success', code = 200 } = {}) {
    if (code === 400 && msg==='success') {
        msg = 'fail';
    }else if(code === 401 && msg==='success'){
        msg = 'No Access'
    }
    return {
        data,
        msg,
        code
    }
}

/**
 * 格式化查询条件
 * @param {Object} params 
 * @param {Array} keys 
 */
function formatParams(params, keys) {
    let res = {}
    for (let item of keys) {
            let key,value
            if(Array.isArray(item)){
                key = item[0];
                let options = item[1];
                value = params[key];
                if(options){
                    value = value===undefined ? options.default : value
                    const falseValue = ['false','0']
                    switch(options.type){
                        case 'number':
                            value = Number(value);
                            break;
                        case 'boolean':
                            value = falseValue.includes(value) ? false : Boolean(value);
                            break;
                        case 'exists':
                            value = { $exists: !falseValue.includes(value) };
                            break;
                    }
                }
            }else{
                key = item;
                value = params[key]
            }

            if(value !== undefined){
                res[key] = value;
            }
        }
    return res;
}


/**
 * 'xxx'格式化成ObjectId('xxx')
 * @param {String|Array} id 
 */

function formatId(id) {console.log('id=',id)
    // 'xxx'
    

    // ['xxxx','xxxx','xxxx']
    if (Array.isArray(id)) {
        return id.map(item => {
            return formatId(item)
        })
    }

    // {$in:['xxxx','xxxx','xxxx']}
    if (typeof id === 'object') {
        let res = {}
        for (let key in id) {
            res[key] = formatId(id[key])
        }
        return res;
    }

    if (/^[a-fA-F0-9]{24}$/.test(id)) {console.log('id->',id)
        return ObjectId(id)
    }
    return id;
}



/**
 * 利用crypto加密解密
 * 
 */

// 加密
function encrypt(data, key, { type = 'aes-256-ecb', outType = 'base64', encode = 'utf8' } = {}) {
    const cipher = crypto.createCipher(type, key);
    // cipher.setAutoPadding(true);
    var crypted = cipher.update(data, encode, outType);
    crypted = cipher.final(outType);
    return crypted;
}
// 解密
function decrypt(encrypted, key, { type = 'aes-256-ecb', outType = 'base64', encode = 'utf8' } = {}) {
    const decipher = crypto.createDecipher(type, key);
    var decrypted = decipher.update(encrypted, outType, encode);
    decrypted = decipher.final(encode);
    return decrypted;
}

function formatPassword(password) {
    // 对称加密
    // const cipher = crypto.createCipher('aes192', key);
    // let crypted = cipher.update(password, 'utf-8', 'hex');
    // crypted += cipher.final('hex');

    // const decipher = crypto.createDecipher('aes192',key)
    // let decrypted = decipher.update(crypted, 'hex', 'utf-8');
    // decrypted += decipher.final('utf-8');

    // 对前端传入的MD5密码加盐
    // const hash = crypto.createHmac('sha256',key);
    // hash.update(password);
    // // hash.update('ABC');
    // password = hash.digest('hex')


    // 对sha256加密的密码进行二次加密
    // password = password.slice(password.length / 2);
    const hash = crypto.createHash('sha256');
    hash.update(password);
    password = hash.digest('hex');
    return password;
}

function formatSort(sort) {
    // sort格式：sort=price,1
    sort = sort.split(',');
    return {
        [sort[0]]: sort[1] || -1 // 默认降序
    };
}

function randomCode(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min
}

module.exports = {
    formatData,
    formatId,
    formatParams,
    formatPassword,
    formatSort,
    encrypt,
    decrypt,
    randomCode,
    token,
    sms,
}